home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume90
/
util
/
ruler_40
/
part01
/
ruler4.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-08
|
12KB
|
451 lines
/* RULER
*
* Opens a borderless WorkBench window in which is contained a ruler
* for the purpose of aligning or constraining text; the default ruler
* is 30 characters with an 8 pixel scale and is intended to help
* prevent entering too-long filenames.
*
* Usage:
*
* CLI> RUN RULER [ size ] [ scale ]
*
* where `size' is the number of ruler markings, and `scale' is the
* width between each marking (a particular font width for example).
*
* Evoking the command with an argument of "?", such as:
*
* CLI> RULER ?
*
* will print out a help message detailing what values are valid for
* your particular Workbench environment.
*
*
* The window, of course, can be moved to any convenient location on the
* screen, and resized with an invisible resizing gadget found in the
* lower right corner.
*
* Version 4.0 29-Dec-1989 (copyright)1989 Chad Netzer and Thad Floryan
*
* Based upon code, idea, and logic from:
*
* Version 1.0 7-Nov-1988 (copyright)1988 Thad Floryan
*
* Revision history:
* 29-December-1989 - (Ver. 4.0) - Added an offset so that you can
* just stick the window on the left edge of the workbench screen,
* and it will automatically be lined up with the characters.
* Fixed some more minor bugs and rearranged the code a bit.
* Added ARP support for those who want it. (CFN)
*
* 09-March-1989 - (Ver. 3.1) - Fixed a visual bug so that scale can
* no longer be less than eight. (CFN)
*
* 06-Dec-1988 - (Ver. 3.0) - Added support for measuring fonts of
* varying widths (selectable scale). (CFN)
*
* 22-Nov-1988 - (Ver. 2.2) - More adjustments to code, No major
* changes. Program size is slightly smaller. (CFN)
*
* 14-Nov-1988 - (Ver. 2.1) - Fixed a few minor (harmless) bugs. The
* right edge of the ruler is now always redrawn after resizing.
* I got rid of that GOTO statement (which in 'C', is considered a
* bug. :-) Version 2.1 now lets you open a ruler to be as low as
* 12 characters wide, which 2.0 only advertised. (CFN)
*
* 13-Nov-1988 - (Ver. 2.0) - I added minor enhancements, most
* noteably, the ability to resize the window, and support for
* overscanned screens. (CFN)
*
*
* Feel welcome to use this program for any non-commercial purposes or
* for your personal learning. Commercial users are requested to contact
* Thad at either:
*
* UUCP: thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad
* BBS: BBS-JC, 415/961-7250 (300/1200/2400), "Thad Floryan" | "SYSOP"
*
* or Chad at:
*
* UUCP: chad@ucscb.ucsc.edu (during school term)
* UUCP: chad@cup.portal.com (holidays, summer, etc.)
* BBS: BBS-JC, 415/961-7250 (300/1200/2400), "Chad Netzer"
*
*
* Building instructions (Manx Aztec C):
*
* ************************
* *** Non-ARP Version ***
* ************************
*
* cc ruler4
* ln ruler4 -lc
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#define NEW(typ) AllocMem((ULONG)sizeof(typ), MEMF_CLEAR)
#define FREE(p,typ) FreeMem(p,(ULONG)sizeof(typ))
#define ever (;;) /* used for infinite loops */
#define FATAL 20 /* exit code */
#define WARN 10 /* exit code */
#define NORMAL 0 /* exit code */
#define LEFT_OFFSET 3L /* "dead space" on left side of ruler margin */
extern void *OpenLibrary();
extern void *OpenWindow();
extern void *GetMsg();
extern void *AllocMem();
extern void ReplyMsg();
void release_resources();
void error_exit();
struct NewWindow window_def =
{
240, 0, /* Initial LeftEdge, TopEdge */
241, 25, /* Default pixel-width, pixel-height */
0, 1, /* DetailPen, BlockPen */
CLOSEWINDOW | /* IDCMP flags */
NEWSIZE,
WINDOWDRAG | /* window flags */
WINDOWDEPTH |
WINDOWCLOSE |
WINDOWSIZING |
SMART_REFRESH |
NOCAREREFRESH |
BORDERLESS |
RMBTRAP,
NULL, /* Gadget list */
NULL, /* checkmark stuff */
(UBYTE *)"", /* window title (to be filled in later) */
NULL, /* custom screen pointer */
NULL, /* bitmap pointer */
97 + LEFT_OFFSET, 0, /* Minwidth, no MinHeight */
-1, 0, /* no MaxWidth, MaxHeight */
WBENCHSCREEN /* screen type */
};
struct Window *window;
struct RastPort *rp;
struct Library *IntuitionBase;
struct Library *GfxBase;
struct Screen *screen;
struct IntuiMessage *sys_message;
ULONG class;
int resource_state;
char *version =
"Text Ruler V4.0 29-Dec-89 \xA91989 Thad Floryan and Chad Netzer"
" "; /* padding for "nice" title */
char *help_text = /* help message on startup */
"\n"
"%40s\n"
"Opens a borderless WorkBench window in which is contained a ruler\n"
"for the purpose of aligning or constraining text; the default ruler\n"
"is 30 characters with an 8 pixel scale and is intended to help\n"
"prevent entering too-long filenames.\n\n"
"Usage:\n\n\t"
"CLI> RUN %s [ size ] [ scale ]\n\n"
"where `size' is the number of ruler markings, and `scale' is the\n"
"width between each marking (a particular font width for example).\n\n"
"`size' must be between 12 and %ld inclusive, and defaults to 30.\n"
"`scale' cannot be greater than %ld or less than 8. The default is 8."
"\n\n";
/**********************************************************************/
main (argc, argv)
int argc;
char *argv[];
{
long fivec; /* pixel size of five chars */
long fsize; /* The font size of ruler scale */
long max_scale; /* The max scale size possible */
long max_width; /* maximum size of ruler */
long w; /* character width of ruler */
long w_lim; /* pixel width (w * fsize) */
long x; /* present window x coordinate */
long y; /* present window y coordinate */
char buf[5];
long success; /* indicates bad return values */
resource_state = 0;
/*
* Open Intuition so we can get the screen size limits.
*/
IntuitionBase = OpenLibrary ("intuition.library", 0L);
if (IntuitionBase == 0L)
{
error_exit("?Cannot open intuition.library\n");
}
++resource_state;
/*
* Get WorkBench screen information
*/
screen = NEW(struct Screen); /* Allocate a buffer for screen data */
if (screen == 0L)
{
release_resources();
error_exit("?ran out of available memory\n");
}
++resource_state;
success = GetScreenData(screen, (ULONG) sizeof (struct Screen),
WBENCHSCREEN, 0L);
if (success == FALSE)
{
error_exit();
}
/*
* Set up defaults...
*/
w = 30L; /* default ruler is 30 chars for a filename */
fsize = 8L; /* default font scale is 8 pixels per char */
/*
* find maximum values, adjusted for morerows
*/
max_width = (screen->Width - LEFT_OFFSET) / 8;
max_scale = (screen->Width - 2) / 12;
/*
* Parse command line to obtain requested parameters.
*/
if (argc > 1)
{
if (*argv[1] == '?' ||
*argv[1] == '-' ||
*argv[1] == 'h' ||
*argv[1] == 'H' )
{
printf( help_text,
version, argv[0], max_width, max_scale);
release_resources();
exit (NORMAL);
}
}
if (argc > 3)
{
printf("?Too many arguments, ``%s ?'' for help\n", argv[0]);
release_resources();
exit (WARN);
}
if ((argc >= 2) && (argc <= 3))
{
w = atol(argv[1]);
if ( w < 12L || w > max_width )
{
printf("?`size' must be >= 12 and <= %ld\n", max_width);
release_resources();
exit (WARN);
}
}
if (argc == 3)
{
fsize = atol(argv[2]);
if (fsize < 8)
{
printf("?Font scale must be at least 8!\n");
release_resources();
exit (WARN);
}
if (fsize > max_scale)
{
printf("?Font size can be NO larger than %ld!\n", max_scale);
release_resources();
exit (WARN);
}
}
/*
* Now calculate window sizing and placement parameters and setup title.
*/
w_lim = w * fsize;
window_def.Width = w_lim + LEFT_OFFSET + 1;
window_def.LeftEdge = (window_def.Width > 300L) ? 0 : 240;
window_def.Title = (UBYTE *)version;
fivec = 5L * fsize;
/*
* Bomb out if requested ruler size would be larger than the screen.
*/
if (window_def.Width > screen -> Width )
{
error_exit("?Ruler too large for WorkBench screen\n");
}
/*
* Open up the graphics library.
*/
GfxBase = OpenLibrary ("graphics.library", 0L);
if (GfxBase == 0L)
{
error_exit("?Cannot open graphics.library\n");
}
++resource_state;
/*
* Open the ruler display window.
*/
window = OpenWindow (&window_def);
if (window == 0L)
{
error_exit("?Cannot open window\n");
}
++resource_state;
/*
* Get pointer to raster port.
*/
rp = window -> RPort;
SetAPen (rp, 0L);
/*
* Use RectFill to blank the window area and set pen for drawing.
*/
for ever
{
SetAPen(rp, 0L);
RectFill(rp, 0L, 10L, w_lim + LEFT_OFFSET, 24L);
/*
* Now set pen to draw.
*/
SetAPen(rp, 1L);
/*
* Because we've used a BORDERLESS window, must fill in some of the
* title-/drag-bar space near the lower left where the text starts.
*/
Move(rp, 28L, 8L);
Draw(rp, 31L, 8L);
/*
* Because we've used a BORDERLESS window, must draw our own line beneath
* the title bar to make the bar the same height as the window gadgets.
* The `28' is the pixel position just to the right of the close gadget.
* The `53' is the pixel width of the depth-arranging gadgets in the upper
* right corner of the window.
*/
Move(rp, 28L, 9L);
Draw(rp, (w_lim + LEFT_OFFSET - 53L), 9L);
/*
* When I use the ruler, I like to jam it up against the left hand side of
* my workbench screen, so that it to measure something on the CLI.
* However, the CLI is offset by a small amount, so I compensate by
* starting the "virtual" area of the ruler a little to the right...
*
* Fill in the offset area that is unused.
*/
RectFill(rp, 0L, 9L, LEFT_OFFSET, 24L);
/*
* Shorten virtual ruler size by subtracting LEFT_OFFSET from w_lim.
*/
/* w_lim -= LEFT_OFFSET;*/
/*
* Draw ruler and text
*/
for (x = 0L; x < (w_lim + fsize); x += fsize)
{
if (x >= w_lim) /* right edge */
{
x = w_lim;
y = 10L;
}
else if (x == 0L) y = 10L; /* left edge */
else if ((x % fivec) == 0L) y = 19L; /* big tic every 5 chars */
else y = 22L; /* small tic every char */
Move (rp, x + LEFT_OFFSET, y);
Draw (rp, x + LEFT_OFFSET, 24L);
/*
* Label ruler.
* The test for position `fivec' (in the Move()) is for centering ``5''
* differently than the centering for two-digit numbers.
*/
if ((x > 0L) && (x < w_lim) && ((x % fivec) == 0L))
{
sprintf (buf, "%2ld", (x / fsize));
Move (rp, (x == fivec) ? (x - 12L + LEFT_OFFSET)
: (x - 8L + LEFT_OFFSET), 17L);
Text (rp, buf, (long) strlen (buf));
}
}
/*
* Wait for gadget activation. No busy-/spin-/wait-loops here!
*/
Wait (1L << window -> UserPort -> mp_SigBit);
/*
* Retrieve LAST message in Message Port
*/
sys_message = GetMsg(window -> UserPort);
class = sys_message -> Class;
ReplyMsg(sys_message);
/*
* Dump uneeded messages (respond only to the last on LIFO queue).
*/
while (sys_message = GetMsg(window -> UserPort))
{
ReplyMsg(sys_message);
}
if (class == CLOSEWINDOW)
{
release_resources();
exit (NORMAL);
}
if (class == NEWSIZE)
{
w_lim = (window -> Width) - 1 - LEFT_OFFSET;
}
}
}
/**********************************************************************
*
* cleanup routine
*
* The ``switch'' on resource_state is to assure we don't attempt to
* free something we don't have. Items are released in the reverse
* order they were obtained (by "falling thru" the cases).
*/
void release_resources()
{
switch (resource_state)
{
case 4: CloseWindow (window);
case 3: CloseLibrary(GfxBase);
case 2: FREE (screen, struct Screen);
case 1: CloseLibrary(IntuitionBase);
}
}
/**********************************************************************
*
* error handler
*/
void error_exit(message)
char *message;
{
if (message == 0L)
{
printf("Internal failure, exiting gracefully...\n");
}
else
{
printf(message);
}
release_resources();
exit (FATAL);
}